using System;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Widgetsphere.Generator.Common.Util;
using Widgetsphere.Generator.Common.GeneratorFramework;

namespace Widgetsphere.Generator.Common.Forms
{
  public partial class ModelTree : UserControl
	{
		#region member variables
		
    private FileInfo _modelFile;
    private IGenerator _generatorProject;
		protected bool _isDirty = false;

		#endregion 

    public ModelTree()
    {
      ReInitializeComponent();
    }

    protected void ReInitializeComponent()
    {
      InitializeComponent();

      this.lvwError.IconWarning = this.imageList1.Images[0];
      this.lvwError.IconError = this.imageList1.Images[1];
      this.lvwError.DoubleClick += new EventHandler(lvwError_DoubleClick);

      this.tvwModel.ShowNodeToolTips = true;
      this.tvwModel.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.mModelTree_AfterSelect);
      this.tvwModel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.mModelTree_MouseUp);
      this.tvwModel.KeyUp += new KeyEventHandler(this.tvwModel_KeyUp);
    }

    #region TreeView Handlers

    private void mModelTree_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
    {
      if (e.Button == MouseButtons.Right)
      {
        TreeNode treeNode = tvwModel.GetNodeAt(e.X, e.Y);
        if (treeNode != null)
        {
          IModelObjectController controller = ((ModelObjectTreeNode)treeNode).Controller;
          ContextMenu cm = new ContextMenu();
          MenuCommand[] commands = controller.GetMenuCommands();
          if (commands != null)
          {
            foreach (MenuCommand tmpMenuCommand in controller.GetMenuCommands())
            {
              cm.MenuItems.Add(tmpMenuCommand);
            }
          }
          cm.Show(this, new Point(e.X, e.Y));
        }
      }
    }

    public void ResetContentPane()
    {
      pnlChild.Controls.Clear();
      pnlChild.Controls.Add(lblNoDesignerMessage);
    }

    private void mModelTree_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
    {
      ModelObjectTreeNode selectedNode = (ModelObjectTreeNode)tvwModel.SelectedNode;
      pnlChild.Controls.Clear();
      pnlChild.Controls.Add(selectedNode.Controller.UIControl);      
    }

    private void tvwModel_KeyUp(object sender, KeyEventArgs e)
    {
      if(e.KeyCode == Keys.Delete)
      {
        IModelObjectController controller = ((ModelObjectTreeNode)this.tvwModel.SelectedNode).Controller;
        controller.DeleteObject();
      }
    }

    #endregion

    #region Methods
    private void BuildTree()
    {
      this.BuildTree(false);
    }

    private void BuildTree(bool expand)
    {
      tvwModel.Nodes.Clear();
      if (this.ModelOpen)
      {
        ((BaseModelObject)this.Generator.RootController.Object).DirtyChanged += new EventHandler(ModelDirtyChanged);
        tvwModel.Nodes.Add(this.Generator.RootController.Node);
        tvwModel.ImageList = this.Generator.ImageList;
      }
    }

    private void ModelDirtyChanged(object sender, System.EventArgs e)
    {
      _isDirty = true;
    }

    private void DTEVerifyComplete(object sender, Widgetsphere.Generator.Common.EventArgs.MessageCollectionEventArgs e)
    {
      this.lvwError.ClearMessages();
      this.lvwError.AddMessages(e.MessageCollection);
    }

    #endregion

    #region ErrorBox Event Handlers

    private void lvwError_DoubleClick(object sender, System.EventArgs e)
    {
      if (this.lvwError.SelectedItems.Count > 0)
      {
        Widgetsphere.Generator.Common.GeneratorFramework.Message message = (Widgetsphere.Generator.Common.GeneratorFramework.Message)this.lvwError.SelectedItems[0].Tag;
        this.tvwModel.SelectedNode = message.Controller.Node;
      }
    }

    #endregion

		#region Property Implementations

    [Browsable(false)]
    public bool ModelOpen
    {
      get { return (_modelFile != null); }
    }

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
    [Browsable(false)]
    public string FileName
    {
      get
      {
        if (ModelOpen)
          return _modelFile.FullName;
        else
          return string.Empty;
      }
			set
			{
				_modelFile = new FileInfo(value);
			}
    }

    [Browsable(false)]
    public IGenerator Generator
    {
      get { return _generatorProject; }
    }
    #endregion

    #region Methods

		public void LoadFile(string filePath)
		{			
      this.CloseModel();
			_modelFile = new FileInfo(filePath);
			_generatorProject = GeneratorHelper.OpenModel(filePath);
      this.BuildTree();
		}

	
		public void CloseModel()
    {
      _modelFile = null;
      _generatorProject = null;
    }

    public void SaveFile(string fileName)
    {
			if (_modelFile != null)
			{
				GeneratorHelper.SaveModelFile(_generatorProject, fileName);
			}
			else
			{
				throw new Exception("Cannot save file none was opened");
			}
    }

    public void SaveModel()
    {
      SaveFile(_modelFile.FullName);      
    }

    public void Verify()
    {
      if (this.Generator != null)
      {
        if (this.Generator.RootController != null)
        {
          try
          {
            this.Enabled = false;
            this.lvwError.ClearMessages();
            this.lvwError.AddMessages(this.Generator.RootController.Verify());
            MessageBox.Show("Verification is complete.", "Complete", MessageBoxButtons.OK, MessageBoxIcon.Information);
          }
          catch (Exception ex)
          {
						MessageBox.Show("An error occurred during the verification process.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            System.Diagnostics.Debug.WriteLine(ex.ToString());
          }
          finally
          {
            this.Enabled = true;
          }

        }
      }
    }

    #endregion
    
  }
}
